home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / chown / chown.c < prev    next >
C/C++ Source or Header  |  1988-07-22  |  4KB  |  226 lines

  1. /*
  2.  * Copyright (c) 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. char copyright[] =
  15. "@(#) Copyright (c) 1988 Regents of the University of California.\n\
  16.  All rights reserved.\n";
  17. #endif /* not lint */
  18.  
  19. #ifndef lint
  20. static char sccsid[] = "@(#)chown.c    5.10 (Berkeley) 4/23/88";
  21. #endif /* not lint */
  22.  
  23. #include <sys/param.h>
  24. #include <sys/stat.h>
  25. #include <sys/dir.h>
  26. #include <pwd.h>
  27. #include <grp.h>
  28. #include <stdio.h>
  29. #include <ctype.h>
  30.  
  31. static int ischown, uid, gid, fflag, rflag, retval;
  32. static char *gname, *myname;
  33.  
  34. /*
  35.  * Forward declarations, to keep gcc happy:
  36.  */
  37.  
  38. extern int setgid(), setuid(), change(), chownerr(), err(), usage();
  39.  
  40. main(argc, argv)
  41.     int argc;
  42.     char **argv;
  43. {
  44.     extern char *optarg;
  45.     extern int optind;
  46.     register char *cp;
  47.     int ch;
  48.     char *index(), *rindex();
  49.  
  50.     myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
  51.     ischown = myname[2] == 'o';
  52.  
  53.     while ((ch = getopt(argc, argv, "Rf")) != EOF)
  54.         switch((char)ch) {
  55.         case 'R':
  56.             rflag++;
  57.             break;
  58.         case 'f':
  59.             fflag++;
  60.             break;
  61.         case '?':
  62.         default:
  63.             usage();
  64.         }
  65.     argv += optind;
  66.     argc -= optind;
  67.  
  68.     if (argc < 2)
  69.         usage();
  70.  
  71.     if (ischown) {
  72.         if (cp = index(*argv, '.')) {
  73.             *cp++ = '\0';
  74.             setgid(cp);
  75.         }
  76.         else
  77.             gid = -1;
  78.         setuid(*argv);
  79.     }
  80.     else {
  81.         uid = -1;
  82.         setgid(*argv);
  83.     }
  84.  
  85.     while (*++argv)
  86.         change(*argv);
  87.     exit(retval);
  88. }
  89.  
  90. static
  91. setgid(s)
  92.     register char *s;
  93. {
  94.     struct group *gr, *getgrnam();
  95.  
  96.     if (!*s) {
  97.         gid = -1;            /* argument was "uid." */
  98.         return;
  99.     }
  100.     for (gname = s; *s && isdigit(*s); ++s);
  101.     if (!*s)
  102.         gid = atoi(gname);
  103.     else {
  104.         if (!(gr = getgrnam(gname))) {
  105.             if (fflag)
  106.                 exit(0);
  107.             fprintf(stderr, "%s: unknown group id: %s\n",
  108.                 myname, gname);
  109.             exit(-1);
  110.         }
  111.         gid = gr->gr_gid;
  112.     }
  113. }
  114.  
  115. static
  116. setuid(s)
  117.     register char *s;
  118. {
  119.     struct passwd *pwd, *getpwnam();
  120.     char *beg;
  121.  
  122.     if (!*s) {
  123.         uid = -1;            /* argument was ".gid" */
  124.         return;
  125.     }
  126.     for (beg = s; *s && isdigit(*s); ++s);
  127.     if (!*s)
  128.         uid = atoi(beg);
  129.     else {
  130.         if (!(pwd = getpwnam(beg))) {
  131.             if (fflag)
  132.                 exit(0);
  133.             fprintf(stderr, "chown: unknown user id: %s\n", beg);
  134.             exit(-1);
  135.         }
  136.         uid = pwd->pw_uid;
  137.     }
  138. }
  139.  
  140. static
  141. change(file)
  142.     char *file;
  143. {
  144.     register DIR *dirp;
  145.     register struct direct *dp;
  146.     struct stat buf;
  147.  
  148.     if (chown(file, uid, gid)) {
  149.         chownerr(file);
  150.         return;
  151.     }
  152.     if (!rflag)
  153.         return;
  154.     if (lstat(file, &buf)) {
  155.         err(file);
  156.         return;
  157.     }
  158.     if ((buf.st_mode & S_IFMT) == S_IFDIR) {
  159.         if (chdir(file) < 0 || !(dirp = opendir("."))) {
  160.             err(file);
  161.             return;
  162.         }
  163.         for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
  164.             if (dp->d_name[0] == '.' && (!dp->d_name[1] ||
  165.                 dp->d_name[1] == '.' && !dp->d_name[2]))
  166.                 continue;
  167.             change(dp->d_name);
  168.         }
  169.         closedir(dirp);
  170.         if (chdir("..")) {
  171.             err("..");
  172.             exit(fflag ? 0 : -1);
  173.         }
  174.     }
  175. }
  176.  
  177. static
  178. chownerr(file)
  179.     char *file;
  180. {
  181.     static int euid = -1, ngroups = -1;
  182.  
  183.     /* check for chown without being root */
  184.     if (uid != -1 && euid == -1 && (euid = geteuid())) {
  185.         if (fflag)
  186.             exit(0);
  187.         err(file);
  188.         exit(-1);
  189.     }
  190.     /* check group membership; kernel just returns EPERM */
  191.     if (gid != -1 && ngroups == -1) {
  192.         int groups[NGROUPS];
  193.  
  194.         ngroups = getgroups(NGROUPS, groups);
  195.         while (--ngroups >= 0 && gid != groups[ngroups]);
  196.         if (ngroups < 0) {
  197.             if (fflag)
  198.                 exit(0);
  199.             fprintf(stderr,
  200.                 "%s: you are not a member of group %s.\n",
  201.                 myname, gname);
  202.             exit(-1);
  203.         }
  204.     }
  205.     err(file);
  206. }
  207.  
  208. static
  209. err(s)
  210.     char *s;
  211. {
  212.     if (fflag)
  213.         return;
  214.     fprintf(stderr, "%s: ", myname);
  215.     perror(s);
  216.     retval = -1;
  217. }
  218.  
  219. static
  220. usage()
  221. {
  222.     fprintf(stderr, "usage: %s [-Rf] %s file ...\n", myname,
  223.         ischown ? "owner[.group]" : "group");
  224.     exit(-1);
  225. }
  226.